package org.chen.flight.controller;

import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.flight.request.FlightSearchRequest;
import org.chen.common.flight.response.OneWayFlightSearchResponse;
import org.chen.common.flight.response.RoundTripFlightSearchResponse;
import org.chen.common.task.ScheduledTask;
import org.chen.common.task.ScheduledTaskRequest;
import org.chen.common.result.ResultVO;
import org.chen.flight.service.FlightService;
import org.chen.flight.service.task.FlightScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

// FlightController.java - 主控制器
@RestController
@Slf4j
@Tag(name = "不重要的接口", description = "不重要的接口")
public class FlightController {

    @Autowired
    private FlightService flightService;

    @Autowired
    private FlightScheduleService flightScheduleService;

    /**
     * 搜索机票 - 第一步获取transactionID，第二步获取详细数据
     */
    @PostMapping("/search")
    @Tag(name = "机票查询接口")
    public ResultVO<?> searchFlights(@RequestBody FlightSearchRequest request) {
        try {
            if ("oneway".equals(request.getTripType())) {
                return searchOneWayFlights(request);
            } else if ("roundtrip".equals(request.getTripType())) {
                return searchRoundTripFlights(request);
            } else {
                return ResultVO.fail("不支持的行程类型: " + request.getTripType());
            }
        } catch (Exception e) {
            log.error("搜索机票失败", e);
            return ResultVO.fail(e.getMessage());
        }
    }

    /**
     * 搜索单程机票
     */
    @PostMapping("/search/oneway")
    @Tag(name = "单程机票查询接口")
    public ResultVO<OneWayFlightSearchResponse> searchOneWayFlights(@RequestBody FlightSearchRequest request) {
        try {
            log.info("收到单程机票搜索请求: {}", request);
            OneWayFlightSearchResponse response = flightService.searchOneWayFlights(request);
            return ResultVO.success(response);
        } catch (Exception e) {
            log.error("单程机票搜索失败", e);
            return ResultVO.fail(OneWayFlightSearchResponse.error("搜索失败: " + e.getMessage()));
        }
    }

    /**
     * 搜索往返机票
     */
    @Tag(name = "往返机票查询接口")
    @PostMapping("/search/roundtrip")
    public ResultVO<RoundTripFlightSearchResponse> searchRoundTripFlights(@RequestBody FlightSearchRequest request) {
        try {
            log.info("收到往返机票搜索请求: {}", request);
            RoundTripFlightSearchResponse response = flightService.searchRoundTripFlights(request);
            return ResultVO.success(response);
        } catch (Exception e) {
            log.error("往返机票搜索失败", e);
            return ResultVO.fail(RoundTripFlightSearchResponse.error("搜索失败: " + e.getMessage()));
        }
    }

    /**
     * 导出单程搜索结果
     */
    @PostMapping("/export/oneway")
    public ResponseEntity<ByteArrayResource> exportOneWayResults(
            @RequestBody OneWayFlightSearchResponse response,
            @RequestParam(defaultValue = "false") boolean exportLowestPriceOnly) {
        try {
            ByteArrayResource resource = flightService.exportOneWaySearchResult(
                    response, response.getSearchRequest(), exportLowestPriceOnly);

            // 修复：处理中文文件名编码问题
            String filename = String.format("单程机票_%s-%s_%s.xlsx",
                    response.getSearchRequest().getDeparture(),
                    response.getSearchRequest().getDestination(),
                    java.time.LocalDate.now().toString());

            // 使用RFC 5987标准处理文件名编码
            String encodedFilename = encodeFilename(filename);

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; " + encodedFilename)
                    .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                    .body(resource);
        } catch (Exception e) {
            log.error("导出单程搜索结果失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 导出往返搜索结果
     */
    @PostMapping("/export/roundtrip")
    public ResponseEntity<ByteArrayResource> exportRoundTripResults(
            @RequestBody RoundTripFlightSearchResponse response,
            @RequestParam(defaultValue = "false") boolean exportLowestPriceOnly) {
        try {
            ByteArrayResource resource = flightService.exportRoundTripSearchResult(
                    response, response.getSearchRequest(), exportLowestPriceOnly);

            // 修复：处理中文文件名编码问题
            String filename = String.format("往返机票_%s-%s_%s.xlsx",
                    response.getSearchRequest().getDeparture(),
                    response.getSearchRequest().getDestination(),
                    java.time.LocalDate.now().toString());

            // 使用RFC 5987标准处理文件名编码
            String encodedFilename = encodeFilename(filename);

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; " + encodedFilename)
                    .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
                    .body(resource);
        } catch (Exception e) {
            log.error("导出往返搜索结果失败", e);
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 编码文件名以支持中文
     * 使用RFC 5987标准
     */
    private String encodeFilename(String filename) {
        // 使用URLEncoder编码文件名
        String encodedFilename = URLEncoder.encode(filename, StandardCharsets.UTF_8)
                .replaceAll("\\+", "%20"); // 替换+为%20以符合RFC标准

        // 构建符合RFC 5987标准的Content-Disposition头
        return String.format("filename=\"%s\"; filename*=UTF-8''%s",
                filename.replaceAll("[^\\x00-\\x7F]", "?"), // ASCII fallback
                encodedFilename);
    }

    /**
     * 获取定时任务列表
     */
    @GetMapping("/scheduled-tasks")
    public ResultVO<List<ScheduledTask>> getScheduledTasks() {
        return ResultVO.success(flightScheduleService.getScheduledTasks());
    }

    /**
     * 创建动态日期定时任务
     */
    @PostMapping("/scheduled-tasks")
    public ResultVO<ScheduledTask> createScheduledTask(@RequestBody ScheduledTaskRequest request) {
        try {
            ScheduledTask task = flightScheduleService.createScheduledTask(request);
            return ResultVO.success(task);
        } catch (Exception e) {
            log.error("创建定时任务失败", e);
            return ResultVO.fail("创建定时任务失败" + e.getMessage());
        }
    }

    /**
     * 删除定时任务
     */
    @DeleteMapping("/scheduled-tasks/{taskId}")
    public ResultVO<String> deleteScheduledTask(@PathVariable String taskId) {
        try {
            flightScheduleService.deleteScheduledTask(taskId);
            return ResultVO.success("操作成功");
        } catch (Exception e) {
            log.error("删除定时任务失败", e);
            return ResultVO.fail("删除定时任务失败" + e.getMessage());
        }
    }

    /**
     * 暂停/恢复定时任务
     */
    @PutMapping("/scheduled-tasks/{taskId}/{action}")
    public ResultVO<String> toggleScheduledTask(@PathVariable String taskId, @PathVariable String action) {
        try {
            flightScheduleService.toggleScheduledTask(taskId, action);
            return ResultVO.success("操作成功");
        } catch (Exception e) {
            log.error("切换任务状态失败", e);
            return ResultVO.fail("切换任务状态失败" + e.getMessage());
        }
    }

    /**
     * 立即执行任务
     */
    @PostMapping("/scheduled-tasks/{taskId}/execute")
    public ResultVO<String> executeScheduledTask(@PathVariable String taskId) {
        try {
            flightScheduleService.executeScheduledTaskNow(taskId);
            return ResultVO.success("操作成功");
        } catch (Exception e) {
            log.error("立即执行任务失败", e);
            return ResultVO.fail("立即执行任务失败" + e.getMessage());
        }
    }

    /**
     * 获取任务执行日志
     */
    @GetMapping("/scheduled-tasks/{taskId}/logs")
    public ResultVO<List<Map<String, Object>>> getTaskLogs(@PathVariable String taskId) {
        try {
            List<Map<String, Object>> taskLogs = flightScheduleService.getTaskLogs(taskId);
            return ResultVO.success(taskLogs);
        } catch (Exception e) {
            log.error("获取任务执行日志", e);
            return ResultVO.fail("获取任务执行日志" + e.getMessage());
        }
    }

    /**
     * 获取定时任务详情（用于编辑时回填数据）
     */
    @GetMapping("/scheduled-tasks/{taskId}")
    public ResultVO<ScheduledTask> getScheduledTask(@PathVariable String taskId) {
        try {
            ScheduledTask task = flightScheduleService.getScheduledTask(taskId);
            if (task == null) {
                return ResultVO.fail("定时任务不存在: " + taskId);
            }
            return ResultVO.success(task);
        } catch (Exception e) {
            log.error("获取定时任务失败: {}", taskId, e);
            return ResultVO.fail("获取定时任务失败: {}" + e.getMessage());
        }
    }

    /**
     * 更新定时任务
     */
    @PutMapping("/scheduled-tasks/{taskId}")
    public ResultVO<ScheduledTask> updateScheduledTask(
            @PathVariable String taskId,
            @RequestBody ScheduledTaskRequest request) {
        try {
            ScheduledTask updatedTask = flightScheduleService.updateScheduledTask(taskId, request);
            return ResultVO.success(updatedTask);
        } catch (Exception e) {
            log.error("更新定时任务失败: {}", taskId, e);
            return ResultVO.fail("更新定时任务失败: " + e.getMessage());
        }
    }
}
